package t_03_aio;

import lombok.SneakyThrows;

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;

public class AIOClient {
    AsynchronousSocketChannel clientChannel;

    public static void main(String[] args) {
        AIOClient client = new AIOClient("localhost", 6666);
        try {
            System.out.println("enter your message to server : ");
            Scanner str = new Scanner(System.in);
            client.doWrite(str.nextLine());
            client.doRead();
        } finally {
            client.doDestory();
        }
    }

    @SneakyThrows
    public AIOClient(String host, int port) {
        // 打开一个 SocketChannel 通道并获取 AsynchronousSocketChannel 实例
        clientChannel = AsynchronousSocketChannel.open();
        InetSocketAddress address = new InetSocketAddress(host, port);
        // 连接到服务器
        clientChannel.connect(address);

        // 连接到服务器并处理连接结果
        // clientChannel.connect(address, null, new CompletionHandler<Void, Void>() {
        //     @Override
        //     public void completed(final Void result, final Void attachment) {
        //         System.out.println("成功连接到服务器!");
        //         try {
        //             // 给服务器发送信息并等待发送完成
        //             clientChannel.write(ByteBuffer.wrap("From client:Hello i am client".getBytes())).get();
        //             ByteBuffer readBuffer = ByteBuffer.allocate(128);
        //             // 阻塞等待接收服务端数据
        //             clientChannel.read(readBuffer).get();
        //             System.out.println(new String(readBuffer.array()));
        //         } catch (InterruptedException | ExecutionException e) {
        //             e.printStackTrace();
        //         }
        //     }
        //
        //     @Override
        //     public void failed(final Throwable exc, final Void attachment) {
        //         exc.printStackTrace();
        //     }
        // });
        // TimeUnit.MINUTES.sleep(Integer.MAX_VALUE);
    }

    public void doWrite(String line) {
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        buffer.put(line.getBytes(StandardCharsets.UTF_8));
        buffer.flip();
        clientChannel.write(buffer);
    }

    @SneakyThrows
    public void doRead() {
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        System.out.println("等待服务端返回数据！");
        // read() 是一个异步方法，实际由 OS 实现，get() 会阻塞，此处使用阻塞是因为后面要把结果打印
        // 也可以去掉 get，但是就必须实现 CompletionHandler，就像 server 端读取数据那样
        clientChannel.read(buffer).get();
        buffer.flip();
        System.out.println("from server: " + new String(buffer.array(), StandardCharsets.UTF_8));
    }

    @SneakyThrows
    public void doDestory() {
        if (null != clientChannel) {
            clientChannel.close();
        }
    }
}
